package com.njcb.ams.service;

import com.njcb.ams.assembler.SysTaskJobConvertor;
import com.njcb.ams.pojo.enumvalue.TriggerType;
import com.njcb.ams.repository.dao.SysTaskJobDAO;
import com.njcb.ams.repository.entity.SysTaskJob;
import com.njcb.ams.scheduler.bean.ScheduleJob;
import com.njcb.ams.scheduler.service.AmsJobSchedulerManager;
import com.njcb.ams.scheduler.utils.JobConstant;
import com.njcb.ams.support.exception.ExceptionUtil;
import com.njcb.ams.util.AmsAssert;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @author liuyanlong
 */
@Service
public class SysTaskJobService {
    private static final Logger logger = LoggerFactory.getLogger(SysTaskJobService.class);
    @Autowired
    private SysTaskJobDAO sysTaskJobDAO;
    @Autowired
    private AmsJobSchedulerManager amsJobSchedulerManager;

    /**
     * 更新任务，新增或修改
     *
     * @throws Exception
     */
    public void updateJob(SysTaskJob sysTaskJob) throws Exception {
        checkTaskJob(sysTaskJob);
        //新增
        if (null == sysTaskJob.getId()) {
            sysTaskJobDAO.insert(sysTaskJob);
            ScheduleJob job = SysTaskJobConvertor.initScheduleJob(sysTaskJob);
            amsJobSchedulerManager.addJob(String.valueOf(job.getJobId()), JobConstant.GROUP_NAME, job);
        } else {//修改
            sysTaskJobDAO.updateByPrimaryKey(sysTaskJob);
            ScheduleJob job = SysTaskJobConvertor.initScheduleJob(sysTaskJob);
            amsJobSchedulerManager.updateJob(String.valueOf(job.getJobId()), JobConstant.GROUP_NAME, job);
        }
    }

    /**
     * 删除任务
     *
     * @param jobId
     * @throws Exception
     */
    public void deleteJob(Integer jobId) throws Exception {
        SysTaskJob sysTaskJob = sysTaskJobDAO.selectByPrimaryKey(jobId);
        sysTaskJobDAO.deleteByPrimaryKey(sysTaskJob.getId());
        ScheduleJob job = SysTaskJobConvertor.initScheduleJob(sysTaskJob);
        amsJobSchedulerManager.deleteJob(String.valueOf(job.getJobId()), job.getJobGroup());
    }

    /**
     * 查询任务
     *
     * @param sysTaskJob
     * @return
     */
    public List<SysTaskJob> taskJobQuery(SysTaskJob sysTaskJob) {
        List<SysTaskJob> allJob = sysTaskJobDAO.selectAll();
        List<ScheduleJob> allSchedule = amsJobSchedulerManager.getAllJob();
        for (SysTaskJob taskJob : allJob) {
            for (ScheduleJob scheduleJob : allSchedule) {
                if (taskJob.getId().equals(scheduleJob.getJobId())) {
                    taskJob.setJobStatus(scheduleJob.getJobStatus());
                    if (null != scheduleJob.getNextTime()) {
                        taskJob.setNextFireTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(scheduleJob.getNextTime()));
                    }
                    try {
                        if (null != taskJob.getLastRunTime()) {
                            Date lastRunTime = new SimpleDateFormat("yyyyMMddHHmmss").parse(taskJob.getLastRunTime());
                            taskJob.setLastRunTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(lastRunTime));
                        }
                    } catch (ParseException e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }
        }
        return allJob;
    }

    /**
     * 任务启动
     *
     * @param sysTaskJob
     * @throws SchedulerException
     */
    public void taskJobStart(SysTaskJob sysTaskJob) throws SchedulerException {
        ScheduleJob scheduleJob = new ScheduleJob();
        scheduleJob.setJobId(sysTaskJob.getId());
        scheduleJob.setJobName(sysTaskJob.getJobName());
        scheduleJob.setJobGroup(JobConstant.GROUP_NAME);
        amsJobSchedulerManager.reJob(String.valueOf(scheduleJob.getJobId()), scheduleJob.getJobGroup(), scheduleJob);
    }

    /**
     * 任务停止
     *
     * @param sysTaskJob
     * @throws SchedulerException
     */
    public void taskJobStop(SysTaskJob sysTaskJob) throws SchedulerException {
        ScheduleJob scheduleJob = new ScheduleJob();
        scheduleJob.setJobId(sysTaskJob.getId());
        scheduleJob.setJobName(sysTaskJob.getJobName());
        scheduleJob.setJobGroup(JobConstant.GROUP_NAME);
        amsJobSchedulerManager.stopJob(String.valueOf(scheduleJob.getJobId()), scheduleJob.getJobGroup());
    }

    /**
     * 任务立即运行
     *
     * @param sysTaskJob
     * @throws SchedulerException
     */
    public void taskJobTrigger(SysTaskJob sysTaskJob) throws SchedulerException {
        ScheduleJob scheduleJob = new ScheduleJob();
        scheduleJob.setJobId(sysTaskJob.getId());
        scheduleJob.setJobName(sysTaskJob.getJobName());
        scheduleJob.setJobGroup(JobConstant.GROUP_NAME);
        amsJobSchedulerManager.triggerJob(String.valueOf(scheduleJob.getJobId()), scheduleJob.getJobGroup());
    }

    public void checkTaskJob(SysTaskJob taskJob){
        AmsAssert.isEnum(TriggerType.class, taskJob.getTriggerType(), "任务[" + taskJob.getJobName() + "]等触发类型[" + taskJob.getTriggerType() + "]非有效枚举");
        if (TriggerType.CRON.getCode().equals(taskJob.getTriggerType())) {
            boolean cronExpressionFlag = CronExpression.isValidExpression(taskJob.getCronExpression());
            if (!cronExpressionFlag) {
                ExceptionUtil.throwAppException("触发类型[" + taskJob.getTriggerType() + "]的任务[" + taskJob.getJobName() + "]的CRON表达式[" + taskJob.getCronExpression() + "]不正确");
            }
            taskJob.setRepeatTime(null);
            taskJob.setRepeatCount(null);
            taskJob.setStartTime("");
            taskJob.setEndTime("");
        }else if(TriggerType.REPEAT.getCode().equals(taskJob.getTriggerType())){
            AmsAssert.notNull(taskJob.getRepeatTime(),"触发类型[" + taskJob.getTriggerType() + "]的任务[" + taskJob.getJobName() + "]的重复时间不能为空");
            AmsAssert.notNull(taskJob.getRepeatCount(),"触发类型[" + taskJob.getTriggerType() + "]的任务[" + taskJob.getJobName() + "]的重复次数不能为空");
            taskJob.setCronExpression("");
        }
    }
}
